#include "output.h"
#include "controller.h"
#include "relay.h"

/* private defines ---------------------------------------------------------- */

/* public variables --------------------------------------------------------- */

/* private function prototype ----------------------------------------------- */
static void output_speed_set(uint8_t out);
static void output_valve_set(uint8_t state);
static void controller_ac_process(void);
static void output_speed_ac_process(void);
static void output_valve_ac_process(void);

/* public function prototype ------------------------------------------------ */

/* 输出逻辑处理 */
void output_process(void)
{
    if(get_fault() == 0)
    {
        controller_ac_process();
        output_speed_ac_process();
        output_valve_ac_process();
    }
    else
    {
        set_out_speed_ac(0);
        set_valve_ac(0);
        output_valve_set(0);
        output_speed_set(SPEED_OUT_OFF);
    }
}

/* 风机输出 */
static void output_speed_set(uint8_t out)
{
    switch(out)
    {
        case SPEED_OUT_OFF:
        {
            relay_set(RELAY_WIND_L, 0);
            relay_set(RELAY_WIND_M, 0);
            relay_set(RELAY_WIND_H, 0);
        }
        break;
        case SPEED_OUT_LOW:
        {
            if(get_relay_state(RELAY_WIND_L) == 0)
            {
                if((get_relay_state(RELAY_WIND_M) == 0) && ((get_relay_state(RELAY_WIND_H) == 0)))
                {
                    relay_set(RELAY_WIND_L, 1);
                }
                else
                {
                    relay_set(RELAY_WIND_M, 0);
                    relay_set(RELAY_WIND_H, 0);
                }
            }
        }
        break;
        case SPEED_OUT_MID:
        {
            if(get_relay_state(RELAY_WIND_M) == 0)
            {
                if((get_relay_state(RELAY_WIND_L) == 0) && ((get_relay_state(RELAY_WIND_H) == 0)))
                {
                    relay_set(RELAY_WIND_M, 1);
                }
                else
                {
                    relay_set(RELAY_WIND_L, 0);
                    relay_set(RELAY_WIND_H, 0);
                }
            }
        }
        break;
        case SPEED_OUT_HIGH:
        {
            if(get_relay_state(RELAY_WIND_H) == 0)
            {
                if((get_relay_state(RELAY_WIND_L) == 0) && ((get_relay_state(RELAY_WIND_M) == 0)))
                {
                    relay_set(RELAY_WIND_H, 1);
                }
                else
                {
                    relay_set(RELAY_WIND_L, 0);
                    relay_set(RELAY_WIND_M, 0);
                }
            }
        }
        break;
    }
}
/* 阀输出 */
static void output_valve_set(uint8_t state)
{
    relay_set(RELAY_VALVE, state);
}
/* 空调控温状态机 */
static void controller_ac_process(void)
{
    signed char tempErr;
    if(get_power_ac() != 0)
    {
        switch(get_ac_mode())
        {
            case ACMODE_AIR:
            {
                set_valve_ac(0);

                set_output_speed_delay(SPEED_OUT_FOREVER);

                switch(get_speedSet_ac())
                {
                    case SPEED_SET_AUTO:
                    {
                        set_speedSet_ac(SPEED_SET_LOW);
                    }
                    case SPEED_SET_LOW:
                    {
                        set_out_speed_ac(SPEED_OUT_LOW);
                    }
                    break;
                    case SPEED_SET_MID:
                    {
                        set_out_speed_ac(SPEED_OUT_MID);
                    }
                    break;
                    case SPEED_SET_HIGH:
                    {
                        set_out_speed_ac(SPEED_OUT_HIGH);
                    }
                    break;
                }
            }
            break;
            case ACMODE_COOL:
            {
                switch(get_controller_ac_step())
                {
                    case 0:
                    {
                        if(get_tempSmp() > get_tempSet_ac())
                        {
                            set_controller_ac_step(1);
                        }
                        else
                        {
                            set_controller_ac_step(2);
                        }
                    }
                    break;
                    case 1:
                    {
                        tempErr = (signed char)get_tempSmp() - (signed char)(get_tempSet_ac() + get_backlash_down_signed());
                        if(tempErr > 0)
                        {
                            set_valve_ac(1);

                            switch(get_speedSet_ac())
                            {
                                case SPEED_SET_AUTO:
                                {
                                    tempErr = (signed char)get_tempSmp() - (signed char)get_tempSet_ac();
                                    if(tempErr >= 3)
                                    {
                                        set_out_speed_ac(SPEED_OUT_HIGH);
                                        set_output_speed_delay(SPEED_OUT_FOREVER);
                                    }
                                    else if(tempErr >= 2)
                                    {
                                        set_out_speed_ac(SPEED_OUT_MID);
                                        set_output_speed_delay(SPEED_OUT_FOREVER);
                                    }
                                    else
                                    {
                                        set_out_speed_ac(SPEED_OUT_LOW);
                                        set_output_speed_delay(SPEED_OUT_FOREVER);
                                    }
                                }
                                break;
                                case SPEED_SET_LOW:
                                {
                                    set_out_speed_ac(SPEED_OUT_LOW);
                                    set_output_speed_delay(SPEED_OUT_FOREVER);
                                }
                                break;
                                case SPEED_SET_MID:
                                {
                                    set_out_speed_ac(SPEED_OUT_MID);
                                    set_output_speed_delay(SPEED_OUT_FOREVER);
                                }
                                break;
                                case SPEED_SET_HIGH:
                                {
                                    set_out_speed_ac(SPEED_OUT_HIGH);
                                    set_output_speed_delay(SPEED_OUT_FOREVER);
                                }
                                break;
                            }
                        }
                        else
                        {
                            set_controller_ac_step(2);
                        }
                    }
                    break;
                    case 2:
                    {
                        tempErr = (signed char)get_tempSmp() - (signed char)(get_tempSet_ac() + get_backlash_up());
                        if(tempErr < 0)
                        {
                            set_valve_ac(0);
                            
                            if(get_speed_ctrl_state() != 0)
                            {
                                if(get_output_speed_delay() > SPEED_OUT_DELAY)
                                {
                                    set_output_speed_delay(SPEED_OUT_DELAY);
                                }
                            }
                            else
                            {
                                set_out_speed_ac(SPEED_OUT_LOW);
                            }
                        }
                        else
                        {
                            set_controller_ac_step(1);
                        }
                    }
                    break;
                }
            }
            break;
            case ACMODE_HEAT:
            {
                switch(get_controller_ac_step())
                {
                    case 0:
                    {
                        if(get_tempSmp() < get_tempSet_ac())
                        {
                            set_controller_ac_step(1);
                        }
                        else
                        {
                            set_controller_ac_step(2);
                        }
                    }
                    break;
                    case 1:
                    {
                        tempErr = (signed char)get_tempSmp() - (signed char)(get_tempSet_ac() + get_backlash_up());
                        if(tempErr < 0)
                        {
                            set_valve_ac(1);

                            switch(get_speedSet_ac())
                            {
                                case SPEED_SET_AUTO:
                                {
                                    tempErr = (signed char)get_tempSet_ac() - (signed char)get_tempSmp();
                                    if(tempErr >= 3)
                                    {
                                        set_out_speed_ac(SPEED_OUT_HIGH);
                                        set_output_speed_delay(SPEED_OUT_FOREVER);
                                    }
                                    else if(tempErr >= 2)
                                    {
                                        set_out_speed_ac(SPEED_OUT_MID);
                                        set_output_speed_delay(SPEED_OUT_FOREVER);
                                    }
                                    else
                                    {
                                        set_out_speed_ac(SPEED_OUT_LOW);
                                        set_output_speed_delay(SPEED_OUT_FOREVER);
                                    }
                                }
                                break;
                                case SPEED_SET_LOW:
                                {
                                    set_out_speed_ac(SPEED_OUT_LOW);
                                    set_output_speed_delay(SPEED_OUT_FOREVER);
                                }
                                break;
                                case SPEED_SET_MID:
                                {
                                    set_out_speed_ac(SPEED_OUT_MID);
                                    set_output_speed_delay(SPEED_OUT_FOREVER);
                                }
                                break;
                                case SPEED_SET_HIGH:
                                {
                                    set_out_speed_ac(SPEED_OUT_HIGH);
                                    set_output_speed_delay(SPEED_OUT_FOREVER);
                                }
                                break;
                                default:
                                    break;
                            }
                        }
                        else
                        {
                            set_controller_ac_step(2);
                        }
                    }
                    break;
                    case 2:
                    {
                        tempErr = (signed char)get_tempSmp() - (signed char)(get_tempSet_ac() + get_backlash_down_signed());
                        if(tempErr > 0)
                        {
                            set_valve_ac(0);
                            
                            if(get_speed_ctrl_state() != 0)
                            {
                                if(get_output_speed_delay() > SPEED_OUT_DELAY)
                                {
                                    set_output_speed_delay(SPEED_OUT_DELAY);
                                }
                            }
                            else
                            {
                                set_out_speed_ac(SPEED_OUT_LOW);
                            }
                        }
                        else
                        {
                            set_controller_ac_step(1);
                        }
                    }
                    break;
                    default:
                        break;
                }
            }
            break;
            case ACMODE_DRY:
            {
                set_valve_ac(0);
                set_out_speed_ac(SPEED_OUT_OFF);
            }
            break;
        }
    }
    else
    {
        set_valve_ac(0);
        set_out_speed_ac(SPEED_OUT_OFF);
    }
}
/* 空调风机输出 */
static void output_speed_ac_process(void)
{
    uint32_t delay = get_speed_delay();
    if(delay != 0)
    {
        delay--;
        set_speed_delay(delay);
    }
    else
    {
        set_out_speed_ac(SPEED_OUT_OFF);
    }

    if(get_relay_mode() == RELAY_MODE_AC)
    {
        output_speed_set(get_out_speed_ac());
    }
}
/* 空调阀输出 */
static void output_valve_ac_process(void)
{
    if(get_relay_mode() == RELAY_MODE_AC)
    {
        output_valve_set(get_valve_state_ac());
    }
}
